package com.sciology.xpathutility.contentassist;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.eclipse.jface.contentassist.IContentAssistSubjectControl;
import org.eclipse.jface.contentassist.ISubjectControlContentAssistProcessor;
import org.eclipse.jface.contentassist.SubjectControlContextInformationValidator;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ContextInformation;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;

import com.sciology.xpathutility.XPathWorkbookActivator;
import com.sciology.xpathutility.utils.XPathUtilLog;

public class XPathContentAssistProcessor implements IContentAssistProcessor, ISubjectControlContentAssistProcessor {

  private final static HashMap proposalStrings = new HashMap();
  private final static ArrayList proposalKeys = new ArrayList();

  static {
    initializeProposals();
  }

  private static void initializeProposals() {
    XPathWorkbookActivator.getDefault().initCompletionsFromFile(proposalStrings, proposalKeys);
  }

  private IContextInformationValidator fValidator = new SubjectControlContextInformationValidator(this);

  public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) {
    return computeCompletionProposals((IContentAssistSubjectControl)null, documentOffset);
  }
  
  public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) {
    return computeContextInformation((IContentAssistSubjectControl)null, documentOffset);
  }

  public char[] getCompletionProposalAutoActivationCharacters() {
    return new char[] {};
  }

  public char[] getContextInformationAutoActivationCharacters() {
    return new char[] {};
  }

  public IContextInformationValidator getContextInformationValidator() {
    return fValidator;
  }

  public String getErrorMessage() {
    return null;
  }

  public ICompletionProposal[] computeCompletionProposals(IContentAssistSubjectControl contentAssistSubjectControl, int documentOffset) {
    Set results = new TreeSet(new XPathCompletionProposalComparator());
    Iterator iter = proposalKeys.iterator();
    while (iter.hasNext()) {
      addProposal((String)iter.next(), contentAssistSubjectControl, documentOffset, results);
    }
    List proposals = new ArrayList(results.size());
    Iterator propIt = results.iterator();
    while (propIt.hasNext()) {
      XPathCompletionProposal proposal = (XPathCompletionProposal)propIt.next();
      String proposalKey = proposal.getKey();
      String displayString = proposal.getDisplayString();
      String additionalInfo = proposal.getAdditionalInfo();
      IContextInformation info = createContextInformation(proposalKey);
      int relativeOffset = proposal.getInsertString().length();
      proposals.add(new CompletionProposal(proposal.getInsertString(), documentOffset, 0, Math.max(0, relativeOffset), null, displayString, info,
          additionalInfo));
    }

    return (ICompletionProposal[])proposals.toArray(new ICompletionProposal[results.size()]);
  }

  public IContextInformation[] computeContextInformation(IContentAssistSubjectControl contentAssistSubjectControl, int documentOffset) {
    return null;
  }

  private void addProposal(String proposalKey, IContentAssistSubjectControl contentAssistSubjectControl, int documentOffset, Set results) {
    XPathCompletionProposal proposal = (XPathCompletionProposal)proposalStrings.get(proposalKey);
    try {
      String text = null;
      text = contentAssistSubjectControl.getDocument().get(0, documentOffset);
      proposal.setText(text);
      if (proposal.isMatch()) {
        results.add(proposal);
      }
    } catch (BadLocationException ble) {
    	XPathUtilLog.logError(XPathWorkbookActivator.getDefault(), ble.getMessage());
    }
  }

  private IContextInformation createContextInformation(String proposalKey) {
    return new ContextInformation(null, "contextDisplayString", "informationDisplayString"); //$NON-NLS-1$ //$NON-NLS-2$
  }
}